package entity

import (
	"fmt"
	"github.com/emirpasic/gods/maps/hashmap"
	"time"
)

type LeaseKey struct {
	serviceName string
	methodName  string
	ip          string
	port        string
}

type Lease struct {
	instanceInfo          Message
	registrationTimestamp int64
	lastUpTimestamp       int64
	duration              int64
}

type Register struct {
	leaseMap *hashmap.Map
}

func (register *Register) Add(msg Message) Error {
	leaseKey, leaseVal := register.GetKV(msg)

	tOldLeaseVal, ok := register.leaseMap.Get(leaseKey)
	if ok {
		oldLeaseVal := tOldLeaseVal.(Lease)
		leaseVal.registrationTimestamp = oldLeaseVal.registrationTimestamp
		fmt.Printf("renew old one : %v", leaseVal.registrationTimestamp)
	}

	register.leaseMap.Put(leaseKey, leaseVal)
	fmt.Printf("add register : %v, status : %v", leaseVal, OK)
	return OK
}

// Renew 重新激活，需要判断是否已经过期，或者是否存在，如果已经过期，不存在该任务都需要返回错误
// ...
func (register *Register) Renew(msg Message) Error {
	curTs := time.Now().Unix()
	leaseKey, leaseVal := register.GetKV(msg)
	tOldLeaseVal, ok := register.leaseMap.Get(leaseKey)
	if !ok {
		return NOT_FIND_P
	}

	oldLeaseVal := tOldLeaseVal.(Lease)
	if curTs-oldLeaseVal.lastUpTimestamp > oldLeaseVal.duration {
		fmt.Printf("%v , is time out, status : %v", oldLeaseVal, TIMEOUT)
		return TIMEOUT
	}
	// 更新任务的时间戳
	register.leaseMap.Put(leaseKey, leaseVal)
	fmt.Printf("%v , is status : %v ", oldLeaseVal, OK)
	return OK
}

// Cancel 重新激活，需要判断是否已经过期，或者是否存在，如果已经过期，不存在该任务都需要返回错误
// ...
func (register *Register) Cancel(msg Message) Error {
	leaseKey, _ := register.GetKV(msg)
	_, ok := register.leaseMap.Get(leaseKey)

	if !ok {
		fmt.Printf("not find: %v, status :%v", leaseKey, NOT_FIND_P)
		return NOT_FIND_P
	}

	// 删除
	register.leaseMap.Remove(leaseKey)
	fmt.Printf("cancel : %v", leaseKey)
	return OK
}

func (register *Register) GetServiceList(msg Message) Error {
	msg.serviceName
}

// New 初始化函数操作，
func New() (r Register) {
	return Register{
		leaseMap: hashmap.New(),
	}
}

// GetKV 重新激活，需要判断是否已经过期，或者是否存在，如果已经过期，不存在该任务都需要返回错误
// ...
func (register *Register) GetKV(msg Message) (LeaseKey, Lease) {
	leaseKey := LeaseKey{
		serviceName: msg.GetServiceName(),
		methodName:  msg.GetMethodName(),
		ip:          msg.GetIp(),
		port:        msg.GetPort(),
	}
	leaseVal := Lease{
		instanceInfo:          msg,
		registrationTimestamp: msg.GetTimestamp(),
		lastUpTimestamp:       msg.GetTimestamp(),
		duration:              msg.GetDuration(),
	}
	return leaseKey, leaseVal
}
